package group
import chisel3._
import chisel3.util.Fill

class group extends  RawModule with chip_config {
  val io = IO(new Bundle{
    val systemclk = Input(Clock())
    val systemRstn = Input(Bool())
    val cardio = new card_IO
    val chipio = Vec(CHIP_NUM,Flipped(new chip_IO))
    val dcout  = new Daisy_IO
    val dcin   = Flipped(new Daisy_IO)
  })
  // BUFG clock
  val u_BUFG = Module(new BUFG).io
  u_BUFG.I := io.systemclk
  val systemRst = !io.systemRstn
  withClockAndReset(u_BUFG.O,systemRst) {
    // Daisy Chain
    io.dcout.cim_dcdata := RegNext(io.dcin.cim_dcdata)
    io.dcout.cim_dcvld  := RegNext(io.dcin.cim_dcvld)
    // counter
    val counter = RegInit(0.U(5.W))
    counter := Mux(counter < CHIP_NUM.U, counter + 1.U, 0.U)
    val enable_array = VecInit(Seq.fill(CHIP_NUM)(false.B))
    // transfer
    val transfer = Module(new transfer()).io
    transfer.systemclk := io.systemclk
    transfer.systemRstn := io.systemRstn
    transfer.cardio <> io.cardio
    // CHIPNUM emitters
    val emitter = Array.fill(CHIP_NUM)(Module(new emitter()).io)
    val cim_fpga_state_list  = Seq.range(0,CHIP_NUM).map{i=> emitter(i).emitterio.cim_fpga_state & enable_array(i) }
    val cim_fpga_result_list = Seq.range(0,CHIP_NUM).map{i=> emitter(i).emitterio.cim_fpga_result & Fill(RESULT_BW,enable_array(i))}
    transfer.emitterio.cim_fpga_state := cim_fpga_state_list.reduce(_|_)
    transfer.emitterio.cim_fpga_result := cim_fpga_result_list.reduce(_|_)

    for (i <- 0 until CHIP_NUM) {
      enable_array(i) := (counter === (i+1).U)
      emitter(i).systemclk := io.systemclk
      emitter(i).systemRstn := io.systemRstn
      emitter(i).emitterio.fpga_cim_cmd := transfer.emitterio.fpga_cim_cmd
      emitter(i).emitterio.fpga_cim_data:= transfer.emitterio.fpga_cim_data
      emitter(i).enable := enable_array(i)
      emitter(i).chipio <> io.chipio(i)
    }
  }
}


